package com.lpf;

import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * TimeInterceptor 就类似于 AOP 的环绕切面
 */
public class TimeInterceptor {

    /**
     * TimeInterceptor 就类似于 AOP 的环绕切面。
     *
     * 这里通过 @SuperCall 注解注入的 Callable 实例可以调到被拦截的目标方法，需要注意的是，在通过 Callable 调用目标方法时，即使目标方法带参数，这里也不用显式的传递。
     * 这里 @Origin 注解注入了被拦截方法对应的 Method 对象。
     */
    @RuntimeType
    public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        try {
            return callable.call(); // 执行原函数
        } finally {
            System.out.println(method.getName() + ":" + (System.currentTimeMillis() - start) + "ms");
        }
    }
}
